/*
 * @Author       : Bing Chen chenbing@iocharger.com
 * @Date         : 2024-05-20 22:18:20
 * @LastEditors  : Bing Chen chenbing@iocharger.com
 * @LastEditTime : 2025-03-15 13:14:17
 * @FilePath     : \openchaoji-corelib\shared\src\OpenChaoJi_utility_transport.c
 * @Description  :本文件定义通用的传输层数据通道建立, 监听, 连接, 断开, 发送数据, 接受数据, 销毁等通用操作, 实现对数据的封装收发
 *
 *
 * Copyright (c) 2025 OpenChaoJi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the icense for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "../include/OpenChaoJi_shared.h"
#include "OpenChaoJi_utility_transport_gbt27930_a.h"
#include "OpenChaoJi_utility_transport_gbt27930_b.h"


/**
 * @brief 本模块的上下文数据结构
 */

struct OpenChaoJi_context_utility_transport {
	int tag;

    /* GBT27930 A类系统的短消息、长消息控制块定义 */
    struct OpenChaoJi_gbt27930_a_urmcb   * gbt27930_a_urmcb;
    struct OpenChaoJi_gbt27930_a_rmcb   * gbt27930_a_rmcb;

    /* GBT27930 B类系统的不需要确认消息、需要确认消息控制块定义 */
    struct OpenChaoJi_gbt27930_b_urmcb  * gbt27930_b_urmcb;
    struct OpenChaoJi_gbt27930_b_rmcb   * gbt27930_b_rmcb;
	struct OpenChaoJi_gbt27930_b_canframe_cache * gbt27930_b_canframe_cache;

    //enum OpenChaoJi_utility_transport_MsgSendResult result;
    int current_msg;
    enum OpenChaoJi_transport_protocol_type transport_protocol_type;

    int (* can_send_func)(void * param, const struct can_pdu * send_pdu);
    int (* can_recv_func)(void * param, struct can_pdu * recv_pdu);

    void * param;
	uint8_t src_addr;
	uint8_t dest_addr;
	uint8_t connected_status;//传输层连接状态，0:未连接，1：已连接
};

bool s_transport_debug_enable = false;
void OpenChaoJi_debug_set_log_module_transport(bool enable)
{
	s_transport_debug_enable = enable;
}

/**
 * @brief 初始化
 *
 * @param info 初始化信息
 * @return 成功返回创建的上下文指针，失败返回NULL。
 */
struct OpenChaoJi_context_utility_transport * OpenChaoJi_utility_transport_init(const struct OpenChaoJi_create_info_utility_transport * info)
{
    struct OpenChaoJi_context_utility_transport * context_transport = (struct OpenChaoJi_context_utility_transport *)OpenChaoJi_os_malloc(sizeof(struct OpenChaoJi_context_utility_transport));

	if (context_transport == NULL) {
        LOG_CRIT("create session fail, malloc fail");
		return NULL;
	}

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_A == CONFIG_YES)
	struct OpenChaoJi_gbt27930_a_urmcb * gbt27930_a_urmcb;
	struct OpenChaoJi_gbt27930_a_rmcb * gbt27930_a_rmcb;
#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)
	struct OpenChaoJi_gbt27930_b_urmcb * gbt27930_b_urmcb;
	struct OpenChaoJi_gbt27930_b_rmcb * gbt27930_b_rmcb;
	struct OpenChaoJi_gbt27930_b_canframe_cache * gbt27930_b_canframe_cache;
#endif

	context_transport->tag = info->tag;
    context_transport->can_send_func = info->can_send_func;
    context_transport->can_recv_func = info->can_recv_func;
    context_transport->transport_protocol_type = info->transport_protocol_type;
	context_transport->src_addr = info->src_addr;
	context_transport->dest_addr = info->dest_addr;
	context_transport->param = info->param;
	context_transport->connected_status = 0;//0:未连接，1：已连接

    /*传输层消息体传输创建*/
    switch (context_transport->transport_protocol_type)
    {

	#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_A == CONFIG_YES)
        case OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_GBT27930_A:

			gbt27930_a_urmcb = OpenChaoJi_transport_gbt27930_a_urm_new(context_transport->param);
		    gbt27930_a_rmcb = OpenChaoJi_transport_gbt27930_a_rm_new(context_transport->param);

            if (gbt27930_a_urmcb == NULL || gbt27930_a_rmcb == NULL)
            {
                LOG_CRIT("transport gbt27930_a_urmcb or gbt27930_a_rmcb is null");
                OpenChaoJi_os_free(context_transport);
				context_transport = NULL;
            }
            else{
				//初始化
				OpenChaoJi_transport_gbt27930_a_urm_bind(gbt27930_a_urmcb, info->tag, info->src_addr, info->dest_addr, info->can_send_func, info->can_recv_func);
				OpenChaoJi_transport_gbt27930_a_urm_init(gbt27930_a_urmcb);

				OpenChaoJi_transport_gbt27930_a_rm_bind(gbt27930_a_rmcb, info->tag, info->src_addr, info->dest_addr, info->can_send_func, info->can_recv_func);
				OpenChaoJi_transport_gbt27930_a_rm_init(gbt27930_a_rmcb);

				context_transport->gbt27930_a_urmcb = gbt27930_a_urmcb;
				context_transport->gbt27930_a_rmcb = gbt27930_a_rmcb;
            }
        break;
	#endif

	#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)
        case OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_GBT27930_B:
            gbt27930_b_urmcb = OpenChaoJi_transport_gbt27930_b_urm_new(context_transport->param);
		    gbt27930_b_rmcb = OpenChaoJi_transport_gbt27930_b_rm_new(context_transport->param);
			gbt27930_b_canframe_cache = OpenChaoJi_transport_gbt27930_b_canframe_cache_new();

            if (gbt27930_b_urmcb == NULL || gbt27930_b_rmcb == NULL || gbt27930_b_canframe_cache == NULL)
            {
                LOG_CRIT("create gbt27930_b_urmcb gbt27930_b_rmcb gbt27930_b_canframe_cache fail, malloc fail");
                OpenChaoJi_os_free(context_transport);
				context_transport = NULL;
            }
            else{

				OpenChaoJi_transport_gbt27930_b_canframe_cache_init(gbt27930_b_canframe_cache);
				OpenChaoJi_transport_gbt27930_b_urm_bind(gbt27930_b_urmcb, info->tag, info->src_addr, info->dest_addr, info->can_send_func, info->can_recv_func);
				OpenChaoJi_transport_gbt27930_b_urm_init(gbt27930_b_urmcb);
				OpenChaoJi_transport_gbt27930_b_rm_bind(gbt27930_b_rmcb, info->tag, info->src_addr, info->dest_addr, info->can_send_func, info->can_recv_func);
				OpenChaoJi_transport_gbt27930_b_rm_init(gbt27930_b_rmcb);

				context_transport->gbt27930_b_canframe_cache = gbt27930_b_canframe_cache;
				context_transport->gbt27930_b_rmcb = gbt27930_b_rmcb;
				context_transport->gbt27930_b_urmcb = gbt27930_b_urmcb;
            }
        break;
 	#endif

        default:
			LOG_ERR("transport_protocol_type is unkonwn");
			OpenChaoJi_os_free(context_transport);
			context_transport = NULL;
        break;
    }

    return context_transport;
}


/**
 * @brief 销毁
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @return 成功返回0，失败返回-1。
 */
int16_t OpenChaoJi_utility_transport_term(struct OpenChaoJi_context_utility_transport * context)
{
	OpenChaoJi_os_free(context->gbt27930_a_urmcb);
    OpenChaoJi_os_free(context->gbt27930_a_rmcb);
    OpenChaoJi_os_free(context->gbt27930_b_urmcb);
    OpenChaoJi_os_free(context->gbt27930_b_rmcb);
	OpenChaoJi_os_free(context->gbt27930_b_canframe_cache);
    OpenChaoJi_os_free(context);

    return 0;
}

/**
 * @brief 复位, 清空收发缓冲区和队列
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @return 成功返回0，失败返回-1。
 */
int16_t OpenChaoJi_utility_transport_reset(struct OpenChaoJi_context_utility_transport * context)
{
	LOG_ALERT("[%d]Transport Reset", context->tag);

	OpenChaoJi_utility_transport_disconnect(context);

    //memset(context, 0x00, sizeof(struct OpenChaoJi_context_utility_transport));
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_A == CONFIG_YES)
    if (context->transport_protocol_type == OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_GBT27930_A)
    {
		OpenChaoJi_transport_gbt27930_a_urm_init(context->gbt27930_a_urmcb);
		OpenChaoJi_transport_gbt27930_a_rm_init(context->gbt27930_a_rmcb);
    }

#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)
    if (context->transport_protocol_type == OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_GBT27930_B)
    {
    	OpenChaoJi_transport_gbt27930_b_canframe_cache_init(context->gbt27930_b_canframe_cache);
		OpenChaoJi_transport_gbt27930_b_urm_init(context->gbt27930_b_urmcb);
		OpenChaoJi_transport_gbt27930_b_rm_init(context->gbt27930_b_rmcb);
    }

#endif

    return 0;
}

/**
 * @brief 服务, 进行长消息或者需要应答消息的自动处理
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @return 成功返回0，失败返回-1。
 */
void OpenChaoJi_utility_transport_service(struct OpenChaoJi_context_utility_transport * context)
{
    struct can_pdu pdu;

    int count = 0;
	//---------------------接收处理--------------------------------
    // 从对端接收数据, 然后根据接收的数据和当前状态决定处理逻辑
    do
    {
        int rtn = (*context->can_recv_func)(context->param, &pdu);

        if (rtn < 0)
        {
            break;
        }

        count++;
		if (s_transport_debug_enable)
		{
			LOG_DATA_TRANSPORT("[%d]<-CAN[%08X][%d]", context->tag, pdu.can_id.uint32_tWord, pdu.can_dlc);
			LOG_DATA_BUFF_TRANSPORT(pdu.data, pdu.can_dlc);
		}

        if((pdu.can_id.bit.ps == context->src_addr) && (pdu.can_id.bit.sa == context->dest_addr))
        {

        #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_A == CONFIG_YES)
            if (context->transport_protocol_type == OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_GBT27930_A)
            {
  				//获取数据帧类型，返回0表示不可靠的消息数据帧，返回1表示可靠的消息数据帧
            	rtn = OpenChaoJi_transport_gbt27930_a_get_canframe_type(&pdu);
            	if (rtn == 0)
            	{
					OpenChaoJi_transport_gbt27930_a_urm_input(&pdu, context->gbt27930_a_urmcb);
                    break; //不可靠消息数据帧接收到，返回，不可靠消息一个循环只能接收一个
				}
				else if (rtn == 1)
				{
                	OpenChaoJi_transport_gbt27930_a_rm_input(&pdu, context->gbt27930_a_rmcb);
				}
            }
        #endif

        #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)
            if (context->transport_protocol_type == OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_GBT27930_B)
            {
            	//数据帧压入缓存中，返回0表示不可靠的消息数据帧，返回1表示可靠的消息数据帧
            	rtn = OpenChaoJi_transport_gbt27930_b_put_canframe_in_cache(&pdu, context->gbt27930_b_canframe_cache);
            	if (rtn == 0)
            	{
            		//是不可靠消息数据帧
					OpenChaoJi_transport_gbt27930_b_urm_input(&pdu, context->gbt27930_b_urmcb);
                    break; //不可靠消息数据帧接收到，返回，不可靠消息一个循环只能接收一个
				}
				else if (rtn == 1)
				{
					//是可靠消息数据帧，给
                	OpenChaoJi_transport_gbt27930_b_rm_input(&pdu, context->gbt27930_b_rmcb);
				}
            }
        #endif
        }
    } while (count < 5);


#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_A == CONFIG_YES)
    if (context->transport_protocol_type == OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_GBT27930_A)
    {

    	OpenChaoJi_utility_transport_gbt27930_a_service(context->gbt27930_a_rmcb);
    }
#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)
    if (context->transport_protocol_type == OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_GBT27930_B)
    {

		OpenChaoJi_utility_transport_gbt27930_b_service(context->gbt27930_b_rmcb);
    }
#endif

}


/**
 * @brief 发送一个完整数据包, 本模块需要自行判断是否是长消息, 如有需要本模块需要保存数据的副本
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @param send_data 待发送的数据结构
 * @param tag 发送消息类型
 * @return 读到数据返回0，读不到数据返回-1。
 */
int16_t OpenChaoJi_utility_transport_send(struct OpenChaoJi_context_utility_transport *context, struct OpenChaoJi_utility_data_buff_send_data * send_data)
{
    // 根据tag不通类型, 把send_data保存到本模块内部缓存或者直接发送等
	int16_t ret = 0;
	struct can_data can_data;
	struct can_pdu pdu;

	can_data.data = send_data->send_data.data;
	can_data.len = send_data->send_data.len;

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_A == CONFIG_YES)

	if (send_data->tag.gbt.data_type == OPENCHAOJI_GBT27930_SYSTEM_A_MSG)
	{
		//A类系统不需要确认消息
		can_data.can_id.bit.sa = send_data->tag.gbt.sa;
		can_data.can_id.bit.ps = send_data->tag.gbt.ps;
		can_data.can_id.bit.pf = send_data->tag.gbt.pf;
		can_data.can_id.bit.dp = 0;
		can_data.can_id.bit.edp = 0;
		can_data.can_id.bit.p = send_data->tag.gbt.p;
		can_data.can_id.bit.rsvd = 0;


		if (send_data->tag.gbt.ack == 0)
	    {
			ret = OpenChaoJi_transport_gbt27930_a_ursm_send(context->gbt27930_a_urmcb, &can_data);
	    }
	    else
	    {
			//A类系统可靠消息处理
			ret = OpenChaoJi_transport_gbt27930_a_rm_write(context->gbt27930_a_rmcb, &can_data);
	    }
	}

#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)

	if (send_data->tag.gbt.data_type == OPENCHAOJI_GBT27930_SYSTEM_B_MSG)
	{
		// b类系统tag没有传地址信息，发送时应该不判地址
		if (send_data->tag.gbt.ack == 0)//GBT27930 B类系统不需要确认消息
	    {
			ret = OpenChaoJi_transport_gbt27930_b_urm_send(context->gbt27930_b_urmcb, &can_data);
	    }
	    else//GBT27930 B类系统需要确认消息
	    {
			//可靠消息处理
			ret = OpenChaoJi_transport_gbt27930_b_rm_write(context->gbt27930_b_rmcb, &can_data);
		}
	}

#endif

	//B类系统CAN数据帧发送，主要是对于链路层版本协商数据进行发送
	if (send_data->tag.gbt.data_type == OPENCHAOJI_GBT27930_SYSTEM_B_LINKAGE_DATA)
	{
		if (send_data->send_data.len > 8)
		{
			//大于8字节的长消息不存在，error
			return -1;
		}

		pdu.can_id.bit.sa = send_data->tag.gbt.sa;
		pdu.can_id.bit.ps = send_data->tag.gbt.ps;
		pdu.can_id.bit.pf = send_data->tag.gbt.pf;
		pdu.can_id.bit.dp = 0;
		pdu.can_id.bit.edp = 0;
		pdu.can_id.bit.p = send_data->tag.gbt.p;
		pdu.can_id.bit.rsvd = 0;

		pdu.can_dlc = send_data->send_data.len;
		memcpy(pdu.data, send_data->send_data.data, send_data->send_data.len);

		// 发送数据帧
	    ret = (*context->can_send_func)(context->param, &pdu);

		if (s_transport_debug_enable)
		{
			LOG_DATA_TRANSPORT("[%d]->b_linkage[%08X][%d]", context->tag, pdu.can_id.uint32_tWord, pdu.can_dlc);
			LOG_DATA_BUFF_TRANSPORT(pdu.data, pdu.can_dlc);
		}
	}

    return ret;
}


/**
 * @brief 读取数据, 本模块会动态申请内存交给调用者, 调用者用完后记得释放内存, 防止内存泄漏
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @param recv_data 待读取数据结构, 注意读取方需要自行free接收的数据区
 * @return 读到数据返回0，读不到数据返回-1。
 */
int16_t OpenChaoJi_utility_transport_recv(struct OpenChaoJi_context_utility_transport *context, struct OpenChaoJi_utility_data_buff_recv_data * data_buff)
{
	struct can_data temp_can_data;

    // 把本地接收缓存的数据包转义后交给上层
    //recv_data->can_id.uint32_tWord = context->gbt27930_b_rmcb->dummy;
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_A == CONFIG_YES)
    if (context->transport_protocol_type == OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_GBT27930_A)
    {
		if (OpenChaoJi_utility_transport_gbt27930_a_got_urm_msg(context->gbt27930_a_urmcb, &temp_can_data) >= 0)
		{
			data_buff->recv_data.data = temp_can_data.data;
			data_buff->recv_data.len = temp_can_data.len;
			data_buff->recv_data.src_free = 1;
			data_buff->tag.all = temp_can_data.can_id.uint32_tWord;
            data_buff->tag.gbt.ack = OPENCHAOJI_GBT27930_MSG_TYPE_URM;
			data_buff->tag.gbt.msg_type = OPENCHAOJI_GBT27930_SYSTEM_A_MSG;//gbt27930_a系统数据
			return 1;
		}
		else if (OpenChaoJi_utility_transport_gbt27930_a_got_rm_msg(context->gbt27930_a_rmcb, &temp_can_data) >= 0)
		{
			data_buff->recv_data.data = temp_can_data.data;
			data_buff->recv_data.len = temp_can_data.len;
			data_buff->recv_data.src_free = 0;
			data_buff->tag.all = temp_can_data.can_id.uint32_tWord;
            data_buff->tag.gbt.ack = OPENCHAOJI_GBT27930_MSG_TYPE_RM;
			data_buff->tag.gbt.msg_type = OPENCHAOJI_GBT27930_SYSTEM_A_MSG;//gbt27930_a系统数据
			return 2;
		}

    }
#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)
    if (context->transport_protocol_type == OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_GBT27930_B)
    {
		struct can_pdu pdu;
		if (OpenChaoJi_transport_gbt27930_b_take_canframe_from_cache(context->gbt27930_b_canframe_cache, &pdu) == 0)
		{
			data_buff->tag.gbt.sa = pdu.can_id.bit.sa;	// id成员不一致
			data_buff->tag.gbt.ps = pdu.can_id.bit.ps;	// id成员不一致
			data_buff->tag.gbt.pf = pdu.can_id.bit.pf;	// id成员不一致
			data_buff->tag.gbt.p = pdu.can_id.bit.p;	// id成员不一致
			data_buff->tag.gbt.msg_type = OPENCHAOJI_GBT27930_SYSTEM_B_LINKAGE_DATA;//gbt27930_b系统数据

			data_buff->recv_data.len = pdu.can_dlc;
			data_buff->recv_data.data = OpenChaoJi_os_malloc(data_buff->recv_data.len);
			if (data_buff->recv_data.data == NULL)
			{
				return -1;
			}
			memcpy(data_buff->recv_data.data, pdu.data, data_buff->recv_data.len);
			data_buff->recv_data.src_free = 0;

			return 0;
		}

        //不需要确认短消息
       	if (OpenChaoJi_utility_transport_gbt27930_b_got_urm_msg(context->gbt27930_b_urmcb, &temp_can_data) >= 0)
       	{
       		data_buff->recv_data.data = temp_can_data.data;
			data_buff->recv_data.len = temp_can_data.len;
			data_buff->recv_data.src_free = 1;
			data_buff->tag.all = temp_can_data.can_id.uint32_tWord;
            data_buff->tag.gbt.ack = OPENCHAOJI_GBT27930_MSG_TYPE_URM;
			data_buff->tag.gbt.msg_type = OPENCHAOJI_GBT27930_SYSTEM_B_MSG;//gbt27930_b系统数据
			return 3;
		}

		int src_free = OpenChaoJi_utility_transport_gbt27930_b_got_rm_msg(context->gbt27930_b_rmcb, &temp_can_data);
		if (src_free >= 0)
		{
			data_buff->recv_data.data = temp_can_data.data;
			data_buff->recv_data.len = temp_can_data.len;
			data_buff->recv_data.src_free = src_free;
			data_buff->tag.all = temp_can_data.can_id.uint32_tWord;
            data_buff->tag.gbt.ack = OPENCHAOJI_GBT27930_MSG_TYPE_RM;
			data_buff->tag.gbt.msg_type = OPENCHAOJI_GBT27930_SYSTEM_B_MSG;//gbt27930_b系统数据
			return 4;
		}
    }
#endif

    return -1;
}


/**
 * @brief 获取不同消息数据包发送结果，调用数据包发送消息后，可通过本模块可查看发送状态结果，主要用于上层查询当前长消息或可靠消息的发送结果
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @param tag 消息类型
 * @return  -1: 发送失败   0: 初始化，复位   1: 发送中   2: 发送完成
 */
enum OpenChaoJi_utility_transport_MsgSendResult OpenChaoJi_utility_transport_get_sending_result(struct OpenChaoJi_context_utility_transport *context, enum OpenChaoJi_gbt27930_msg_type tag);


/**
 * @brief 传输层数据交互链接，对于GBT27930 的CAN传输，调用返回连接成功
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @return 连接成功返回0，失败返回-1。
 */
int16_t OpenChaoJi_utility_transport_connect(struct OpenChaoJi_context_utility_transport *context)
{
	context->connected_status = 1;

    return 0;
}

/**
 * @brief 传输层数据交互链接，对于GBT27930 的CAN传输，调用返回连接成功断开
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @return 连接断开成功返回0，连接断开失败返回-1。
 */
int16_t OpenChaoJi_utility_transport_disconnect(struct OpenChaoJi_context_utility_transport *context)
{
	context->connected_status = 0;

    return 0;
}

int16_t OpenChaoJi_utility_transport_is_connected(struct OpenChaoJi_context_utility_transport *context)
{
	return context->connected_status;
}

/**
 * @brief 关闭传输层可靠消息的所有连接，可靠短消息发送，长消息接收和发送状态过程
 *
 * @param context 系统上下文指针，包含必要的环境信息。
 * @return 连接成功返回0，失败返回-1。
 */
int16_t OpenChaoJi_utility_transport_close(struct OpenChaoJi_context_utility_transport *context)
{

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_A == CONFIG_YES)
    if (context->transport_protocol_type == OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_GBT27930_A)
    {

		return 0;
    }
#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)
    if (context->transport_protocol_type == OPENCHAOJI_TRANSPORT_PROTOCOL_TYPE_GBT27930_B)
    {
		OpenChaoJi_transport_gbt27930_b_rsm_shutdown(context->gbt27930_b_rmcb);
		OpenChaoJi_transport_gbt27930_b_rlm_shutdown_wr(context->gbt27930_b_rmcb);
		OpenChaoJi_transport_gbt27930_b_rlm_shutdown_rd(context->gbt27930_b_rmcb);

		return 0;
    }
#endif

    return -1;
}



